package com.CST.service.impl.ys;

import com.CST.common.StaticVariable;
import com.CST.common.constant.Constants;
import com.CST.dto.ys.YearDTO;
import com.CST.dto.ys.YsBusinessTargetDTO;
import com.CST.entity.cb.BdSysUser;
import com.CST.entity.ys.*;
import com.CST.mapper.cst.cb.BdSysUserMapper;
import com.CST.mapper.cst.ys.YsAccountDetailMapper;
import com.CST.mapper.cst.ys.YsAppealRecordMapper;
import com.CST.mapper.cst.ys.YsBusinessTargetMapper;
import com.CST.mapper.cst.ys.YsSubjectMapper;
import com.CST.service.ys.YsBusinessTargetService;
import com.CST.service.ys.YsComplaintService;
import com.CST.util.ExcelTransfer;
import com.CST.util.HttpUtil;
import com.CST.util.PageHelperTool;
import com.CST.vo.ys.*;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cw
 * @since 2023-05-06
 */
@Service
public class YsBusinessTargetServiceImpl extends ServiceImpl<YsBusinessTargetMapper, YsBusinessTarget> implements YsBusinessTargetService {

    private final ExcelTransfer<YsBusinessTargetVO> excelTransfer;

    private final ExcelTransfer<YsBusinessTarget> excelImport;

    @Autowired
    private YsAccountDetailMapper ysAccountDetailMapper;

    @Autowired
    private YsComplaintService complaintService;

    @Autowired
    private BdSysUserMapper userMapper;

    @Autowired
    private YsSubjectMapper ysSubjectMapper;

    @Autowired
    private YsAppealRecordMapper ysAppealRecordMapper;

    public YsBusinessTargetServiceImpl(ExcelTransfer<YsBusinessTargetVO> excelTransfer,ExcelTransfer<YsBusinessTarget> excelImport) {
        this.excelTransfer = excelTransfer;
        this.excelImport = excelImport;
    }

    /**
     * 新增
     * @param ysBusinessTarget info
     * @return 结果
     */
    @Override
    public Integer insertYsBusinessTarget(YsBusinessTarget ysBusinessTarget) {
        ysBusinessTarget.setNum(baseMapper.selectMaxId()+1);
        ysBusinessTarget.setInsertFlag(1);
        ysBusinessTarget.setCreateTime(LocalDateTime.now());
        ysBusinessTarget.setCreateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        ysBusinessTarget.setUpdateTime(LocalDateTime.now());
        ysBusinessTarget.setUpdateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        return baseMapper.insert(ysBusinessTarget);
    }

    /**
     * 修改
     * @param ysBusinessTarget ysBusinessTarget
     * @return result
     */
    @Override
    public Integer updateYsBusinessTarget(YsBusinessTarget ysBusinessTarget) {
        // 首先去修订记录表中根据用友编号查询，是否存在这条数据的编辑记录
        int count = 0;
        if (ysBusinessTarget.getNum() != null){
            count = baseMapper.selectRecordIsExist(ysBusinessTarget.getNum());
        }
        switch (count){
            case 0:
                // 查询数据插入到修订记录表
                YsBusinessTargetVO info = baseMapper.selectInfoById(ysBusinessTarget.getId());
                YsBusinessTargetRecords record = recordSetting("编辑", 0);
                baseMapper.insertRecord(info,record);
                // 逻辑删除
                baseMapper.deleteToUpdateById(ysBusinessTarget.getId());
                ysBusinessTarget.setNum(ysBusinessTarget.getId());
                break;
            case 1:
                // 物理删除
                baseMapper.deleteById(ysBusinessTarget.getId());
                ysBusinessTarget.setNum(ysBusinessTarget.getNum());
                break;
            default:
                break;
        }

        // 更改申诉状态-- 根据编号查询到相应到申诉数据，修改申诉状态
        BdSysUser user = userMapper.getUserById(HttpUtil.getRequestHeaderInfo(Constants.USER_ID));
//        BdSysUser user = userMapper.getUserById("283E3761-5300-43B0-9629-3C175E29D813");
        Optional.ofNullable(user).orElseThrow(()-> new RuntimeException("用户未登录"));
        YsAppealRecord record = new YsAppealRecord();
        record.setNum(Math.toIntExact(ysBusinessTarget.getNum()));
        record.setStatus(2);
        record.setHandleTime(LocalDateTime.now());
        record.setHandler(user.getId());
        ysAppealRecordMapper.updateByNum(record);

        // 来源 1业务职能，2管理职能-费用类，3管理职能资本类。4管理职能业务配套指标
        YsSubject ysSubject = ysSubjectMapper.selectById(ysBusinessTarget.getSubjectId());
        Optional.ofNullable(ysSubject).orElseThrow(()-> new RuntimeException("预算科目不存在"));
        complaintService.saveEntity(YsComplaint.builder()
                .recipient(StaticVariable.LOG_YS_COMPLAINT_RECIPIENT_1)
                .source(StaticVariable.LOG_YS_COMPLAINT_SOURCE_1)
                .operate(StaticVariable.LOG_YS_COMPLAINT_OPERATE_2)
                .acceptContent(StaticVariable.LOG_YS_COMPLAINT_CONTEXT_HEAD_2
                        + ysSubject.getSubjectName() +"("
                        + ysSubject.getSubjectCode() + ")"
                        + StaticVariable.LOG_YS_COMPLAINT_CONTEXT_2)
                .jumpPage(StaticVariable.LOG_YS_COMPLAINT_PAGE_1)
                .complaintUser(user.getUserName())
                .build());

        ysBusinessTarget.setCreateTime(LocalDateTime.now());
        ysBusinessTarget.setCreateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        ysBusinessTarget.setUpdateTime(LocalDateTime.now());
        ysBusinessTarget.setUpdateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        return baseMapper.insert(ysBusinessTarget);
    }

    private static YsBusinessTargetRecords recordSetting(String 编辑, int revokeFlag) {
        YsBusinessTargetRecords record = new YsBusinessTargetRecords();
        record.setOperContent(编辑);
        record.setOperTime(LocalDateTime.now());
        record.setOperBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        record.setRevokeFlag(revokeFlag);
        return record;
    }

    /**
     * 删除
     * @param id id
     * @return result
     */
    @Override
    public Integer deleteYsBusinessTarget(Long id) {
        // 插入修订记录表格
        YsBusinessTargetVO info = baseMapper.selectInfoById(id);
        if(info.getNum() == null){
            info.setNum(info.getId());
        }
        YsBusinessTargetRecords record = recordSetting("删除", 1);
        baseMapper.insertRecord(info,record);
        return baseMapper.updateDeleteFlagById(id);
    }

    /**
     * 回显
     * @param id id
     * @return result
     */
    @Override
    public YsBusinessTargetVO selectInfoById(Long id) {
        return baseMapper.selectInfoById(id);
    }

    @Override
    public PageInfo<YsBusinessTargetVO> getYsBusinessTargetList(YsBusinessTargetDTO ysBusinessTargetDTO) {
        List<YsBusinessTargetVO> result = baseMapper.selectListByDto(ysBusinessTargetDTO);
        return PageHelperTool.excutePageInfo(result,ysBusinessTargetDTO.getPageNum(),ysBusinessTargetDTO.getPageSize());
    }

    /**
     * 发布
     * @param dto 默认不传参数，数据全部发布
     * @return result
     */
    @Override
    public Boolean releaseData(YsBusinessTargetDTO dto) {
        // 删除数据
        baseMapper.deleteRE();
        List<YsBusinessTargetVO> result = baseMapper.selectListByDto(dto);
        if (result.size() == 0) {
            return true;
        }
        int total = result.size();
        int fromIndex = 0;
        List<YsBusinessTargetVO> insertList = new ArrayList<>();
        for (YsBusinessTargetVO item : result) {
            fromIndex++;
            insertList.add(item);
            if (fromIndex % 50 == 0 && fromIndex <= total) {
                baseMapper.insertRE(insertList);
                insertList = new ArrayList<>();
            }
        }
        if (CollectionUtils.isNotEmpty(insertList)) {
            baseMapper.insertRE(insertList);
        }
        return true;
    }


    /**
     * 撤销
     * @param id id
     * @return result
     */
    @Override
    public Boolean revokeRecord(Long id) {
        // 判断相同的编号是否存在
        YsBusinessTarget ysBusinessTarget = baseMapper.selectById(id);
        if (ysBusinessTarget != null){
            throw new RuntimeException("相同编号的数据已经存在了");
        }
        baseMapper.updateFlagByNum(id);
        // 删除记录表数据
        baseMapper.deleteRecordById(id);
        return true;
    }

    @Override
    public PageInfo<YsBusinessTargetRecordVO> selectRecordList(YsBusinessTargetDTO dto) {
        List<YsBusinessTargetRecordVO> resultList = baseMapper.selectRecordList(dto);
        return PageHelperTool.excutePageInfo(resultList,dto.getPageNum(),dto.getPageSize());
    }

    /**
     * 继承
     * @param dto 参数
     * @return result
     */
    @Override
    public Boolean extendsData(YearDTO dto) {
        baseMapper.deleteByPeriod(dto.getSecondYearAndMonth());
        List<YsBusinessTarget> infoList = baseMapper.selectYearAndMonthDateList(dto.getFirstYearAndMonth());
        if (infoList.size() == 0){
            return true;
        }
        infoList.forEach(s->{
            s.setPeriod(dto.getSecondYearAndMonth());
            s.setCreateTime(LocalDateTime.now());
            s.setUpdateTime(LocalDateTime.now());
            s.setCreateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
            s.setUpdateBy(HttpUtil.getRequestHeaderInfo(Constants.USER_NAME));
        });
        return  baseMapper.insertBatch(infoList);
    }

    /**
     * 下载模版
     * @param response
     */
    @Override
    public void download(HttpServletResponse response) {
        // 查询出所有的预算科目信息--只查询出所有的管理职能
        List<YsSubjectVO> list = ysSubjectMapper.selectThirstChild(6);
        writeExcel(response,list);

    }

    private void writeExcel(HttpServletResponse response, List<YsSubjectVO> list) {
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = "target";
            response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");

            //调用方法进行写操作
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            //获取sheet0对象
            WriteSheet mainSheet = EasyExcel.writerSheet(0, "业务配套量指标").head(YsBusinessTargetImportVO.class).build();
            List<YsBusinessTargetImportVO> voList = new ArrayList<>();
            list.stream().forEach(s->{
                YsBusinessTargetImportVO vo = new YsBusinessTargetImportVO();
                vo.setSubjectId(s.getId());
                vo.setSubjectCode(s.getSubjectCode());
                vo.setSubjectName(s.getSubjectName());
                voList.add(vo);
            });
            excelWriter.write(voList,  mainSheet);

            //关闭流
            excelWriter.finish();
        } catch (Exception e) {
            throw new RuntimeException("下载失败");
        }
    }

    /**
     * 导出
     * @param response response
     * @param dto 查询参数
     */
    @Override
    public void exportExcelYsBusinessTarget(HttpServletResponse response, YsBusinessTargetDTO dto) {
        excelTransfer.exportExcel(response, baseMapper.selectListByDto(dto), "业务量配套指标", "sheet",
                YsBusinessTargetVO.class);
    }

    /**
     * 导入
     * @param file file
     */
    @Override
    public void importExcelYsBusinessTarget(MultipartFile file) {
        excelImport.importExcel(file,this,YsBusinessTarget.class);
    }

}
